﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace CSharpWrapper
{
    internal class ConfVoiceWrapper : IConferenceVoice
    {
        public delegate void OnDeviceChangeDelegate();
        public delegate void OnDisconnectVoiceServerDelegate(int result);

        [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct ConfVoiceCallback
        {
            public OnDeviceChangeDelegate OnDeviceChangeDelegate_;
            public OnDisconnectVoiceServerDelegate OnDisconnectVoiceServerDelegate_;
        }

        public void OnDeviceChange()
        {
            foreach (IConferenceVoiceObserver observer in observer_list_)
                observer.OnDeviceChange();
        }

        public void OnDisconnectVoiceServer(int result) {
            foreach (IConferenceVoiceObserver observer in observer_list_)
                observer.OnDisconnectVoiceServer(result);
        }

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_set_callback")]
        private static extern void lm_conf_voice_set_callback(IntPtr instance, ref ConfVoiceCallback callback);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetCodecType")]
        private static extern int lm_conf_voice_SetCodecType(IntPtr instance, int codec_type, int delay_mode);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetCodecType")]
        private static extern int lm_conf_voice_GetCodecType(IntPtr instance, ref int codec_type, ref int delay_mode);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetCodecTypeWithInputDevice")]
        private static extern int lm_conf_voice_SetCodecTypeWithInputDevice(IntPtr instance, int input_type, int codec_type, int delay_mode, int rate);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetCodecTypeWithInputDevice")]
        private static extern int lm_conf_voice_GetCodecTypeWithInputDevice(IntPtr instance, int input_type, ref int codec_type, ref int delay_mode, ref int rate);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_IsValidDelayMode")]
        private static extern int lm_conf_voice_IsValidDelayMode(IntPtr instance, int codec_type, int delay_mode);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetNumOfInputDevices")]
        private static extern int lm_conf_voice_GetNumOfInputDevices(IntPtr instance, ref int nums);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetNumOfOutputDevices")]
        private static extern int lm_conf_voice_GetNumOfOutputDevices(IntPtr instance, ref int nums);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetInputDeviceName")]
        private static extern int lm_conf_voice_GetInputDeviceName(IntPtr instance, int index, 
            StringBuilder name, int name_size, StringBuilder guid, int guid_size);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetOutputDeviceName")]
        private static extern int lm_conf_voice_GetOutputDeviceName(IntPtr instance, int index, 
            StringBuilder name, int name_size, StringBuilder guid, int guid_size);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetDefaultInputDeviceName")]
        private static extern int lm_conf_voice_GetDefaultInputDeviceName(IntPtr instance, 
            StringBuilder name, int name_size, StringBuilder guid, int guid_size);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetDefaultOutputDeviceName")]
        private static extern int lm_conf_voice_GetDefaultOutputDeviceName(IntPtr instance, 
            StringBuilder name, int name_size, StringBuilder guid, int guid_size);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetCurrentInputDeviceName")]
        private static extern int lm_conf_voice_GetCurrentInputDeviceName(IntPtr instance, 
            StringBuilder name, int name_size, StringBuilder guid, int guid_size);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetCurrentOutputDeviceName")]
        private static extern int lm_conf_voice_GetCurrentOutputDeviceName(IntPtr instance, 
            StringBuilder name, int name_size, StringBuilder guid, int guid_size);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetDefaultInputDeviceIndex")]
        private static extern int lm_conf_voice_GetDefaultInputDeviceIndex(IntPtr instance, ref int index);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetDefaultOutputDeviceIndex")]
        private static extern int lm_conf_voice_GetDefaultOutputDeviceIndex(IntPtr instance, ref int index);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetCurrentInputDeviceIndex")]
        private static extern int lm_conf_voice_GetCurrentInputDeviceIndex(IntPtr instance, ref int index);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetCurrentOutputDeviceIndex")]
        private static extern int lm_conf_voice_GetCurrentOutputDeviceIndex(IntPtr instance, ref int index);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetInputDevice")]
        private static extern int lm_conf_voice_SetInputDevice(IntPtr instance, int index);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetOutputDevice")]
        private static extern int lm_conf_voice_SetOutputDevice(IntPtr instance, int index);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetInputVolume")]
        private static extern int lm_conf_voice_SetInputVolume(IntPtr instance, int volume);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetInputVolume")]
        private static extern int lm_conf_voice_GetInputVolume(IntPtr instance, ref int volume);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetOutputVolume")]
        private static extern int lm_conf_voice_SetOutputVolume(IntPtr instance, int volume);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetOutputVolume")]
        private static extern int lm_conf_voice_GetOutputVolume(IntPtr instance, ref int volume);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetInputVoiceLevel")]
        private static extern int lm_conf_voice_GetInputVoiceLevel(IntPtr instance, ref int level);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetOutputVoiceLevel")]
        private static extern int lm_conf_voice_GetOutputVoiceLevel(IntPtr instance, String account, ref int level);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetOutputVoiceLevel2")]
        private static extern int lm_conf_voice_GetOutputVoiceLevel2(IntPtr instance, int node, ref int level);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetLoudspeakerStatus")]
        private static extern int lm_conf_voice_SetLoudspeakerStatus(IntPtr instance, int enabled);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetEcStatus")]
        private static extern int lm_conf_voice_SetEcStatus(IntPtr instance, int enabled, int mode);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetNsStatus")]
        private static extern int lm_conf_voice_SetNsStatus(IntPtr instance, int enabled, int mode);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetAgcStatus")]
        private static extern int lm_conf_voice_SetAgcStatus(IntPtr instance, int enabled, int mode);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetAecmMode")]
        private static extern int lm_conf_voice_SetAecmMode(IntPtr instance, int mode, int enableCNG);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetVADStatus")]
        private static extern int lm_conf_voice_SetVADStatus(IntPtr instance, int enable, int mode, int disableDTX);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetLoudspeakerStatus")]
        private static extern int lm_conf_voice_GetLoudspeakerStatus(IntPtr instance, ref int enabled);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetEcStatus")]
        private static extern int lm_conf_voice_GetEcStatus(IntPtr instance, ref int enabled, ref int mode);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetNsStatus")]
        private static extern int lm_conf_voice_GetNsStatus(IntPtr instance, ref int enabled, ref int mode);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetAgcStatus")]
        private static extern int lm_conf_voice_GetAgcStatus(IntPtr instance, ref int enabled, ref int mode);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetAecmMode")]
        private static extern int lm_conf_voice_GetAecmMode(IntPtr instance, ref int mode, ref int enabledCNG);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetVADStatus")]
        private static extern int lm_conf_voice_GetVADStatus(IntPtr instance, ref int enabled, ref int mode, ref int disabledDTX);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_EnableDriftCompensation")]
        private static extern int lm_conf_voice_EnableDriftCompensation(IntPtr instance, int enable);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_DriftCompensationEnabled")]
        private static extern int lm_conf_voice_DriftCompensationEnabled(IntPtr instance, ref int enable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetDelayOffsetMs")]
        private static extern int lm_conf_voice_SetDelayOffsetMs(IntPtr instance, int offset);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_DelayOffsetMs")]
        private static extern int lm_conf_voice_DelayOffsetMs(IntPtr instance, ref int offset);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_EnableHighPassFilter")]
        private static extern int lm_conf_voice_EnableHighPassFilter(IntPtr instance, int enable);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_IsHighPassFilterEnabled")]
        private static extern int lm_conf_voice_IsHighPassFilterEnabled(IntPtr instance, ref int enable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_EnableInput")]
        private static extern int lm_conf_voice_EnableInput(IntPtr instance, int enabled);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_EnableOutput")]
        private static extern int lm_conf_voice_EnableOutput(IntPtr instance, int enabled);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetInputState")]
        private static extern int lm_conf_voice_GetInputState(IntPtr instance, ref int enabled);
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetOutputState")]
        private static extern int lm_conf_voice_GetOutputState(IntPtr instance, ref int enabled);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_DisablePlaybackInput")]
        private static extern int lm_conf_voice_DisablePlaybackInput(IntPtr instance, int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_DisableIPCameraInput")]
        private static extern int lm_conf_voice_DisableIPCameraInput(IntPtr instance, int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_DisableMediaPlayerInput")]
        private static extern int lm_conf_voice_DisableMediaPlayerInput(IntPtr instance, int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_DisableExternalDeviceInput")]
        private static extern int lm_conf_voice_DisableExternalDeviceInput(IntPtr instance, int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_DisablePlaybackInputLocalOutput")]
        private static extern int lm_conf_voice_DisablePlaybackInputLocalOutput(IntPtr instance, int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_DisableIPCameraInputLocalOutput")]
        private static extern int lm_conf_voice_DisableIPCameraInputLocalOutput(IntPtr instance, int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_DisableMediaPlayerInputLocalOutput")]
        private static extern int lm_conf_voice_DisableMediaPlayerInputLocalOutput(IntPtr instance, int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_DisableExternalDeviceInputLocalOutput")]
        private static extern int lm_conf_voice_DisableExternalDeviceInputLocalOutput(IntPtr instance, int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetDisablePlaybackInputState")]
        private static extern int lm_conf_voice_GetDisablePlaybackInputState(IntPtr instance, ref int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetDisableIPCameraInputState")]
        private static extern int lm_conf_voice_GetDisableIPCameraInputState(IntPtr instance, ref int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetDisableMediaPlayerInputState")]
        private static extern int lm_conf_voice_GetDisableMediaPlayerInputState(IntPtr instance, ref int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetDisableExternalDeviceInputState")]
        private static extern int lm_conf_voice_GetDisableExternalDeviceInputState(IntPtr instance, ref int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetDisablePlaybackInputLocalOutputState")]
        private static extern int lm_conf_voice_GetDisablePlaybackInputLocalOutputState(IntPtr instance, ref int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetDisableIPCameraInputLocalOutputState")]
        private static extern int lm_conf_voice_GetDisableIPCameraInputLocalOutputState(IntPtr instance, ref int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetDisableMediaPlayerInputLocalOutputState")]
        private static extern int lm_conf_voice_GetDisableMediaPlayerInputLocalOutputState(IntPtr instance, ref int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetDisableExternalDeviceInputLocalOutputState")]
        private static extern int lm_conf_voice_GetDisableExternalDeviceInputLocalOutputState(IntPtr instance, ref int disable);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StartPlayingFileLocallyFromFile")]
        private static extern int lm_conf_voice_StartPlayingFileLocallyFromFile(
	        IntPtr instance, 
	        ref int node,
	        String fileName,
	        int loop,
	        int format,
	        float volumeScaling,
	        int startPointMs,
	        int stopPointMs);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StartPlayingFileLocallyFromStream")]
        private static extern int lm_conf_voice_StartPlayingFileLocallyFromStream(
	        IntPtr instance, 
	        ref int node,
	        ref byte stream, int stream_len,
	        int format,
	        float volumeScaling,
	        int startPointMs, int stopPointMs);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StopPlayingFileLocallyWithNode")]
        private static extern int lm_conf_voice_StopPlayingFileLocallyWithNode(IntPtr instance, int node);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_IsPlayingFileLocallyWithNode")]
        private static extern int lm_conf_voice_IsPlayingFileLocallyWithNode(IntPtr instance, int node);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StartPlayingFileAsMicrophoneFromFile")]
        private static extern int lm_conf_voice_StartPlayingFileAsMicrophoneFromFile(
	        IntPtr instance, 
	        String fileName,
	        int loop ,
	        int mixWithMicrophone,
	        int format,
	        float volumeScaling);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StartPlayingFileAsMicrophoneFromStream")]
        private static extern int lm_conf_voice_StartPlayingFileAsMicrophoneFromStream(
	        IntPtr instance,
            ref byte stream, int stream_len,
	        int mixWithMicrophone,
	        int format,
	        float volumeScaling);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StopPlayingFileAsMicrophone")]
        private static extern int lm_conf_voice_StopPlayingFileAsMicrophone(IntPtr instance);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_IsPlayingFileAsMicrophone")]
        private static extern int lm_conf_voice_IsPlayingFileAsMicrophone(IntPtr instance);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StartRecordingAccountPlayoutToFile")]
        private static extern int lm_conf_voice_StartRecordingAccountPlayoutToFile(
	        IntPtr instance, 
	        String account,
	        String fileName,
	        int codecint,
	        int maxSizeBytes);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StartRecordingAccountPlayoutToStream")]
        private static extern int lm_conf_voice_StartRecordingAccountPlayoutToStream(
	        IntPtr instance, 
	        String account,
            ref byte stream, int stream_len,
	        int codecint);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StopRecordingAccountPlayout")]
        private static extern int lm_conf_voice_StopRecordingAccountPlayout(IntPtr instance, String account);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StartRecordingAllPlayoutToFile")]
        private static extern int lm_conf_voice_StartRecordingAllPlayoutToFile(
	        IntPtr instance, 
	        String fileName,
	        int codec,
	        int maxSizeBytes);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StartRecordingAllPlayoutToStream")]
        private static extern int lm_conf_voice_StartRecordingAllPlayoutToStream(
	        IntPtr instance,
            ref byte stream, int stream_len, int codec);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StopRecordingAllPlayout")]
        private static extern int lm_conf_voice_StopRecordingAllPlayout(IntPtr instance);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StartRecordingMicrophoneToFile")]
        private static extern int lm_conf_voice_StartRecordingMicrophoneToFile(IntPtr instance, String fileName, int codec, int maxSizeBytes);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StartRecordingMicrophoneToStream")]
        private static extern int lm_conf_voice_StartRecordingMicrophoneToStream(IntPtr instance, ref byte stream, int stream_len, int codec);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_StopRecordingMicrophone")]
        private static extern int lm_conf_voice_StopRecordingMicrophone(IntPtr instance);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_AddIPCamera")]
        private static extern int lm_conf_voice_AddIPCamera(IntPtr instance, ref LMIPCameraInfo info, int camera_channel);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_RemoveIPCamera")]
        private static extern int lm_conf_voice_RemoveIPCamera(IntPtr instance, int identity, int camera_channel);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_AddExternalRAWDataInputDevice")]
        private static extern int lm_conf_voice_AddExternalRAWDataInputDevice(IntPtr instance, int sampleRate, int channel, int identity);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_RemoveExternalRAWDataInputDevice")]
        private static extern int lm_conf_voice_RemoveExternalRAWDataInputDevice(IntPtr instance, int identity);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_IncomingExternalInputRAWData")]
        private static extern int lm_conf_voice_IncomingExternalInputRAWData(IntPtr instance, int identity, ref byte data, int data_len);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_AddExternalRTPDataInputDevice")]
        private static extern int lm_conf_voice_AddExternalRTPDataInputDevice(IntPtr instance, int identity);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_RemoveExternalRTPDataInputDevice")]
        private static extern int lm_conf_voice_RemoveExternalRTPDataInputDevice(IntPtr instance, int identity);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_IncomingExternalInputRTPData")]
        private static extern int lm_conf_voice_IncomingExternalInputRTPData(IntPtr instance, int identity, ref byte data, int data_len, int delay_mode);

        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_SetVoiceIOMode")]
        private static extern int lm_conf_voice_SetVoiceIOMode(IntPtr instance, int mode);
  
        [DllImport("c_wrapper.dll", EntryPoint = "lm_conf_voice_GetVoiceIOMode")]
        private static extern int lm_conf_voice_GetVoiceIOMode(IntPtr instance, ref int mode);

        private IntPtr c_instance_;
        private List<IConferenceVoiceObserver> observer_list_;
        private ConfVoiceCallback conf_voice_callback_;

        public ConfVoiceWrapper(IntPtr c_instance)
        {
            c_instance_ = c_instance;
            observer_list_ = new List<IConferenceVoiceObserver>();
            conf_voice_callback_ = new ConfVoiceCallback();
            conf_voice_callback_.OnDeviceChangeDelegate_ = new OnDeviceChangeDelegate(OnDeviceChange);
            conf_voice_callback_.OnDisconnectVoiceServerDelegate_ = new OnDisconnectVoiceServerDelegate(OnDisconnectVoiceServer);
            lm_conf_voice_set_callback(c_instance, ref conf_voice_callback_);
        }


        #region IConferenceVoice 成员

        public int AddObserver(IConferenceVoiceObserver observer)
        {
            if (observer_list_.Contains(observer))
                return -1;
            observer_list_.Add(observer);
            return 0;
        }

        public int RemoveObserver(IConferenceVoiceObserver observer)
        {
            observer_list_.Remove(observer);
            return 0;
        }

        public int SetCodecType(LMVoiceCodecModes codec_type, LMVoiceDelayModes delay_mode)
        {
            return lm_conf_voice_SetCodecType(c_instance_, (int)codec_type, (int)delay_mode);
        }

        public int GetCodecType(ref LMVoiceCodecModes codec_type, ref LMVoiceDelayModes delay_mode)
        {
            int v = 0;
            int v2 = 0;
            int ret = lm_conf_voice_GetCodecType(c_instance_, ref v, ref v2);
            codec_type = (LMVoiceCodecModes)v;
            delay_mode = (LMVoiceDelayModes)v2;
            return ret;
        }

        public int SetCodecTypeWithInputDevice(LMVoiceDeviceType input_type,
            LMVoiceCodecModes codec_type, LMVoiceDelayModes delay_mode, int rate)
        {
            return lm_conf_voice_SetCodecTypeWithInputDevice(c_instance_, (int)input_type, (int)codec_type, (int)delay_mode, rate);
        }

        public int GetCodecTypeWithInputDevice(LMVoiceDeviceType input_type,
            ref LMVoiceCodecModes codec_type, ref LMVoiceDelayModes delay_mode, ref int rate)
        {
            int v = 0;
            int v2 = 0;
            int ret = lm_conf_voice_GetCodecTypeWithInputDevice(c_instance_, (int)input_type, ref v, ref v2, ref rate);
            codec_type = (LMVoiceCodecModes)v;
            delay_mode = (LMVoiceDelayModes)v2;
            return ret;  
        }

        public bool IsValidDelayMode(LMVoiceCodecModes codec_type, LMVoiceDelayModes delay_mode)
        {
            return lm_conf_voice_IsValidDelayMode(c_instance_, (int)codec_type, (int)delay_mode) != 0;
        }

        public int GetNumOfInputDevices(ref int nums)
        {
            return lm_conf_voice_GetNumOfInputDevices(c_instance_, ref nums);
        }

        public int GetNumOfOutputDevices(ref int nums)
        {
            return lm_conf_voice_GetNumOfOutputDevices(c_instance_, ref nums);
        }

        public int GetInputDeviceName(int index, StringBuilder name, StringBuilder guid)
        {
            name.Capacity = 512;
            guid.Capacity = 512;
            return lm_conf_voice_GetInputDeviceName(c_instance_, index, name, 512, guid, 512);
        }

        public int GetOutputDeviceName(int index, StringBuilder name, StringBuilder guid)
        {
            name.Capacity = 512;
            guid.Capacity = 512;
            return lm_conf_voice_GetOutputDeviceName(c_instance_, index, name, 512, guid, 512);
        }

        public int GetDefaultInputDeviceName(StringBuilder name, StringBuilder guid)
        {
            name.Capacity = 512;
            guid.Capacity = 512;
            return lm_conf_voice_GetDefaultInputDeviceName(c_instance_, name, 512, guid, 512);
        }

        public int GetDefaultOutputDeviceName(StringBuilder name, StringBuilder guid)
        {
            name.Capacity = 512;
            guid.Capacity = 512;
            return lm_conf_voice_GetDefaultOutputDeviceName(c_instance_, name, 512, guid, 512);
        }

        public int GetCurrentInputDeviceName(StringBuilder name, StringBuilder guid)
        {
            name.Capacity = 512;
            guid.Capacity = 512;
            return lm_conf_voice_GetCurrentInputDeviceName(c_instance_, name, 512, guid, 512);
        }

        public int GetCurrentOutputDeviceName(StringBuilder name, StringBuilder guid)
        {
            name.Capacity = 512;
            guid.Capacity = 512;
            return lm_conf_voice_GetCurrentOutputDeviceName(c_instance_, name, 512, guid, 512);
        }

        public int GetDefaultInputDeviceIndex(ref int index)
        {
            return lm_conf_voice_GetDefaultInputDeviceIndex(c_instance_, ref index);
        }

        public int GetDefaultOutputDeviceIndex(ref int index)
        {
            return lm_conf_voice_GetDefaultOutputDeviceIndex(c_instance_, ref index);
        }

        public int GetCurrentInputDeviceIndex(ref int index)
        {
            return lm_conf_voice_GetCurrentInputDeviceIndex(c_instance_, ref index);
        }

        public int GetCurrentOutputDeviceIndex(ref int index)
        {
            return lm_conf_voice_GetCurrentOutputDeviceIndex(c_instance_, ref index);
        }

        public int SetInputDevice(int index)
        {
            return lm_conf_voice_SetInputDevice(c_instance_, index);
        }

        public int SetOutputDevice(int index)
        {
            return lm_conf_voice_SetOutputDevice(c_instance_, index);
        }

        public int SetInputVolume(int volume)
        {
            return lm_conf_voice_SetInputVolume(c_instance_, volume);
        }

        public int GetInputVolume(ref int volume)
        {
            return lm_conf_voice_GetInputVolume(c_instance_, ref volume);
        }

        public int SetOutputVolume(int volume)
        {
            return lm_conf_voice_SetOutputVolume(c_instance_, volume);
        }

        public int GetOutputVolume(ref int volume)
        {
            return lm_conf_voice_GetOutputVolume(c_instance_, ref volume);
        }

        public int GetInputVoiceLevel(ref int level)
        {
            return lm_conf_voice_GetInputVoiceLevel(c_instance_, ref level);
        }

        public int GetOutputVoiceLevel(string account, ref int level)
        {
            return lm_conf_voice_GetOutputVoiceLevel(c_instance_, account, ref level);
        }

        public int GetOutputVoiceLevel(int node, ref int level)
        {
            return lm_conf_voice_GetOutputVoiceLevel2(c_instance_, node, ref level);
        }

        public int SetLoudspeakerStatus(bool enabled)
        {
            return lm_conf_voice_SetLoudspeakerStatus(c_instance_, enabled ? 1 : 0);
        }

        public int SetEcStatus(bool enabled, LMEcModes mode)
        {
            return lm_conf_voice_SetEcStatus(c_instance_, enabled ? 1 : 0, (int)mode);
        }

        public int SetNsStatus(bool enabled, LMNsModes mode)
        {
            return lm_conf_voice_SetNsStatus(c_instance_, enabled ? 1 : 0, (int)mode);
        }

        public int SetAgcStatus(bool enabled, LMAgcModes mode)
        {
            return lm_conf_voice_SetAgcStatus(c_instance_, enabled ? 1 : 0, (int)mode);
        }

        public int SetAecmMode(LMAecmModes mode, bool enableCNG)
        {
            return lm_conf_voice_SetAecmMode(c_instance_, (int)mode, enableCNG ? 1 : 0);
        }

        public int SetVADStatus(bool enable, LMVadModes mode, bool disableDTX)
        {
            return lm_conf_voice_SetVADStatus(c_instance_, enable ? 1 : 0, (int)mode, disableDTX ? 1 : 0);
        }

        public int GetLoudspeakerStatus(ref bool enabled)
        {
            int v = 0;
            int ret =  lm_conf_voice_GetLoudspeakerStatus(c_instance_, ref v);
            enabled = v != 0;
            return ret;
        }

        public int GetEcStatus(ref bool enabled, ref LMEcModes mode)
        {
            int v = 0;
            int v1 = 0;
            int ret = lm_conf_voice_GetEcStatus(c_instance_, ref v, ref v1);
            enabled = v != 0;
            mode = (LMEcModes)v1;
            return ret;
        }

        public int GetNsStatus(ref bool enabled, ref LMNsModes mode)
        {
            int v = 0;
            int v1 = 0;
            int ret = lm_conf_voice_GetNsStatus(c_instance_, ref v, ref v1);
            enabled = v != 0;
            mode = (LMNsModes)v1;
            return ret;
        }

        public int GetAgcStatus(ref bool enabled, ref LMAgcModes mode)
        {
            int v = 0;
            int v1 = 0;
            int ret = lm_conf_voice_GetAgcStatus(c_instance_, ref v, ref v1);
            enabled = v != 0;
            mode = (LMAgcModes)v1;
            return ret;
        }

        public int GetAecmMode(ref LMAecmModes mode, ref bool enabledCNG)
        {
            int v = 0;
            int v1 = 0;
            int ret = lm_conf_voice_GetAecmMode(c_instance_, ref v1, ref v);
            enabledCNG = v != 0;
            mode = (LMAecmModes)v1;
            return ret;
        }

        public int GetVADStatus(ref bool enabled, ref LMVadModes mode, ref bool disabledDTX)
        {
            int v = 0;
            int v1 = 0;
            int v2 = 0;
            int ret = lm_conf_voice_GetVADStatus(c_instance_, ref v, ref v1, ref v2);
            enabled = v != 0;
            mode = (LMVadModes)v1;
            disabledDTX = v2 != 0;
            return ret;
        }

        public int EnableDriftCompensation(bool enable)
        {
            return lm_conf_voice_EnableDriftCompensation(c_instance_, enable ? 1 : 0);
        }

        public int DriftCompensationEnabled(ref bool enable)
        {
            int v = 0;
            int ret = lm_conf_voice_DriftCompensationEnabled(c_instance_, ref v);
            enable = v != 0;
            return ret;
        }

        public int SetDelayOffsetMs(int offset)
        {
            return lm_conf_voice_SetDelayOffsetMs(c_instance_, offset);
        }

        public int DelayOffsetMs(ref int offset)
        {
            return lm_conf_voice_DelayOffsetMs(c_instance_, ref offset);
        }

        public int EnableHighPassFilter(bool enable)
        {
            return lm_conf_voice_EnableHighPassFilter(c_instance_, enable ? 1 : 0);
        }

        public int IsHighPassFilterEnabled(ref bool enable)
        {
            int v = 0;
            int ret = lm_conf_voice_DriftCompensationEnabled(c_instance_, ref v);
            enable = v != 0;
            return ret;
        }

        public int EnableInput(bool enabled)
        {
            return lm_conf_voice_EnableInput(c_instance_, enabled ? 1 : 0);
        }

        public int EnableOutput(bool enabled)
        {
            return lm_conf_voice_EnableOutput(c_instance_, enabled ? 1 : 0);
        }

        public int GetInputState(ref bool enabled)
        {
            int v = 0;
            int ret = lm_conf_voice_GetInputState(c_instance_, ref v);
            enabled = v != 0;
            return ret;
        }

        public int GetOutputState(ref bool enabled)
        {
            int v = 0;
            int ret = lm_conf_voice_GetOutputState(c_instance_, ref v);
            enabled = v != 0;
            return ret;
        }

        public int DisablePlaybackInput(bool disabled)
        {
            return lm_conf_voice_DisablePlaybackInput(c_instance_, disabled ? 1 : 0);
        }

        public int DisableIPCameraInput(bool disabled)
        {
            return lm_conf_voice_DisableIPCameraInput(c_instance_, disabled ? 1 : 0);
        }

        public int DisableMediaPlayerInput(bool disabled)
        {
            return lm_conf_voice_DisableMediaPlayerInput(c_instance_, disabled ? 1 : 0);
        }

        public int DisableExternalDeviceInput(bool disabled)
        {
            return lm_conf_voice_DisableExternalDeviceInput(c_instance_, disabled ? 1 : 0);
        }

        public int DisablePlaybackInputLocalOutput(bool disabled)
        {
            return lm_conf_voice_DisablePlaybackInputLocalOutput(c_instance_, disabled ? 1 : 0);
        }

        public int DisableIPCameraInputLocalOutput(bool disabled)
        {
            return lm_conf_voice_DisableIPCameraInputLocalOutput(c_instance_, disabled ? 1 : 0);
        }

        public int DisableMediaPlayerInputLocalOutput(bool disabled)
        {
            return lm_conf_voice_DisableMediaPlayerInputLocalOutput(c_instance_, disabled ? 1 : 0);
        }

        public int DisableExternalDeviceInputLocalOutput(bool disabled)
        {
            return lm_conf_voice_DisableExternalDeviceInputLocalOutput(c_instance_, disabled ? 1 : 0);
        }

        public int GetDisablePlaybackInputState(ref bool disabled)
        {
            int v = 0;
            int ret = lm_conf_voice_GetDisablePlaybackInputState(c_instance_, ref v);
            disabled = v != 0;
            return ret;
        }

        public int GetDisableIPCameraInputState(ref bool disabled)
        {
            int v = 0;
            int ret = lm_conf_voice_GetDisableIPCameraInputState(c_instance_, ref v);
            disabled = v != 0;
            return ret;
        }

        public int GetDisableMediaPlayerInputState(ref bool disabled)
        {
            int v = 0;
            int ret = lm_conf_voice_GetDisableMediaPlayerInputState(c_instance_, ref v);
            disabled = v != 0;
            return ret;
        }

        public int GetDisableExternalDeviceInputState(ref bool disabled)
        {
            int v = 0;
            int ret = lm_conf_voice_GetDisableExternalDeviceInputState(c_instance_, ref v);
            disabled = v != 0;
            return ret;
        }

        public int GetDisablePlaybackInputLocalOutputState(ref bool disabled)
        {
            int v = 0;
            int ret = lm_conf_voice_GetDisablePlaybackInputLocalOutputState(c_instance_, ref v);
            disabled = v != 0;
            return ret;
        }

        public int GetDisableIPCameraInputLocalOutputState(ref bool disabled)
        {
            int v = 0;
            int ret = lm_conf_voice_GetDisableIPCameraInputLocalOutputState(c_instance_, ref v);
            disabled = v != 0;
            return ret;
        }

        public int GetDisableMediaPlayerInputLocalOutputState(ref bool disabled)
        {
            int v = 0;
            int ret = lm_conf_voice_GetDisableMediaPlayerInputLocalOutputState(c_instance_, ref v);
            disabled = v != 0;
            return ret;
        }

        public int GetDisableExternalDeviceInputLocalOutputState(ref bool disabled)
        {
            int v = 0;
            int ret = lm_conf_voice_GetDisableExternalDeviceInputLocalOutputState(c_instance_, ref v);
            disabled = v != 0;
            return ret;
        }

        public int StartPlayingFileLocally(ref int node, string fileName,
            bool loop, LMVoiceFileFormats format, float volumeScaling, int startPointMs, int stopPointMs)
        {
            return lm_conf_voice_StartPlayingFileLocallyFromFile(c_instance_, ref node, fileName,
                loop ? 1 : 0, (int)format, volumeScaling, startPointMs, stopPointMs);
        }

        public int StartPlayingFileLocally(ref int node, byte[] stream,
            LMVoiceFileFormats format, float volumeScaling, int startPointMs, int stopPointMs)
        {
            return lm_conf_voice_StartPlayingFileLocallyFromStream(c_instance_, ref node, ref stream[0],
                stream.Length, (int)format, volumeScaling, startPointMs, stopPointMs);
        }

        public int StopPlayingFileLocally(int node)
        {
            return lm_conf_voice_StopPlayingFileLocallyWithNode(c_instance_, node);
        }

        public int IsPlayingFileLocally(int node)
        {
            return lm_conf_voice_IsPlayingFileLocallyWithNode(c_instance_, node);
        }

        public int StartPlayingFileAsMicrophone(string fileName, bool loop,
            bool mixWithMicrophone, LMVoiceFileFormats format, float volumeScaling)
        {
            return lm_conf_voice_StartPlayingFileAsMicrophoneFromFile(c_instance_, fileName, loop ? 1 : 0, mixWithMicrophone ? 1 : 0,
                (int)format, volumeScaling);
        }

        public int StartPlayingFileAsMicrophone(byte[] stream,
            bool mixWithMicrophone, LMVoiceFileFormats format, float volumeScaling)
        {
            return lm_conf_voice_StartPlayingFileAsMicrophoneFromStream(c_instance_, ref stream[0], stream.Length, mixWithMicrophone ? 1 : 0,
                (int)format, volumeScaling);
        }

        public int StopPlayingFileAsMicrophone()
        {
            return lm_conf_voice_StopPlayingFileAsMicrophone(c_instance_);
        }

        public int IsPlayingFileAsMicrophone()
        {
            return lm_conf_voice_IsPlayingFileAsMicrophone(c_instance_);
        }

        public int StartRecordingPlayout(string account, string fileName, 
            LMVoiceCodecModes codec, int maxSizeBytes = -1)
        {
            return lm_conf_voice_StartRecordingAccountPlayoutToFile(c_instance_, account, fileName, (int)codec, maxSizeBytes);
        }

        public int StartRecordingPlayout(string account, byte[] stream, LMVoiceCodecModes codec)
        {
            return lm_conf_voice_StartRecordingAccountPlayoutToStream(c_instance_, account, ref stream[0], stream.Length, (int)codec);
        }

        public int StopRecordingPlayout(string account)
        {
            return lm_conf_voice_StopRecordingAccountPlayout(c_instance_, account);
        }

        public int StartRecordingPlayout(string fileName, LMVoiceCodecModes codec, int maxSizeBytes)
        {
            return lm_conf_voice_StartRecordingAllPlayoutToFile(c_instance_, fileName, (int)codec, maxSizeBytes);
        }

        public int StartRecordingPlayout(byte[] stream, LMVoiceCodecModes codec)
        {
            return lm_conf_voice_StartRecordingAllPlayoutToStream(c_instance_, ref stream[0], stream.Length, (int)codec);
        }

        public int StopRecordingPlayout()
        {
            return lm_conf_voice_StopRecordingAllPlayout(c_instance_);
        }

        public int StartRecordingMicrophone(string fileName, LMVoiceCodecModes codec, int maxSizeBytes)
        {
            return lm_conf_voice_StartRecordingMicrophoneToFile(c_instance_, fileName, (int)codec, maxSizeBytes);
        }

        public int StartRecordingMicrophone(byte[] stream, LMVoiceCodecModes codec)
        {
            return lm_conf_voice_StartRecordingMicrophoneToStream(c_instance_, ref stream[0], stream.Length, (int)codec);
        }

        public int StopRecordingMicrophone()
        {
            return lm_conf_voice_StopRecordingMicrophone(c_instance_);
        }

        public int AddIPCamera(LMIPCameraInfo info, int camera_channel)
        {
            return lm_conf_voice_AddIPCamera(c_instance_, ref info, camera_channel);
        }

        public int RemoveIPCamera(int identity, int camera_channel)
        {
            return lm_conf_voice_RemoveIPCamera(c_instance_, identity, camera_channel);
        }

        public int AddExternalRAWDataInputDevice(int sampleRate, int channel, int identity)
        {
            return lm_conf_voice_AddExternalRAWDataInputDevice(c_instance_, sampleRate, channel, identity);
        }

        public int RemoveExternalRAWDataInputDevice(int identity)
        {
            return lm_conf_voice_RemoveExternalRAWDataInputDevice(c_instance_, identity);
        }

        public int IncomingExternalInputRAWData(int identity, byte[] data)
        {
            return lm_conf_voice_IncomingExternalInputRAWData(c_instance_, identity, ref data[0], data.Length);
        }

        public int AddExternalRTPDataInputDevice(int identity)
        {
            return lm_conf_voice_AddExternalRTPDataInputDevice(c_instance_, identity);
        }

        public int RemoveExternalRTPDataInputDevice(int identity)
        {
            return lm_conf_voice_RemoveExternalRTPDataInputDevice(c_instance_, identity);
        }

        public int IncomingExternalInputRTPData(int identity, byte[] data, LMVoiceDelayModes delay_mode)
        {
            return lm_conf_voice_IncomingExternalInputRTPData(c_instance_, identity, ref data[0], data.Length, (int)delay_mode);
        }

        public int SetVoiceIOMode(LMVoiceIOModes mode)
        {
            return lm_conf_voice_SetVoiceIOMode(c_instance_, (int)mode);
        }

        public int GetVoiceIOMode(ref LMVoiceIOModes mode)
        {
            int v = 0;
            int ret = lm_conf_voice_GetVoiceIOMode(c_instance_, ref v);
            mode = (LMVoiceIOModes)v;
            return v;
        }

        #endregion
    }
}
